package com.own.component.common.base.service;

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.own.component.common.base.entity.BaseBo;
import com.own.component.common.base.entity.BaseMap;
import com.own.component.common.base.entity.BaseQuery;
import com.own.component.common.base.entity.po.BaseBean;
import com.own.component.common.base.entity.vo.BaseBeanVo;
import com.own.component.common.model.UpdateModel;
import lombok.NonNull;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * BaseBindTwoService
 *
 * @author chenxueli
 * @version 1.0.0
 * @date 2022-06-15 03:14:15
 */
public interface BaseBindTwoService<
        PO extends BaseBean,
        BO extends BaseBo<PO>,
        VO extends BaseBeanVo<PO>,
        MAP extends BaseMap<PO>,
        QUERY extends BaseQuery>
        extends BaseService<PO, BO, VO, MAP, QUERY> {

    /**
     * 获取绑定的数据
     *
     * @param pk 绑定的主id
     * @return 绑定标识
     */
    List<PO> listBindPoByPk(@NonNull Long pk);

    /**
     * 获取绑定的数据
     *
     * @param fk 绑定的副id
     * @return 绑定标识
     */
    List<PO> listBindPoByFk(@NonNull Long fk);

    /**
     * 获取绑定的数据
     *
     * @param pk     绑定的主id
     * @param bindId 绑定的id
     * @return 绑定标识
     */
    PO getBindPo(@NonNull Long pk, @NonNull Long bindId);

    /**
     * 验证绑定的数据
     *
     * @param pk     绑定的主id
     * @param bindId 绑定的id
     */
    void checkBindPo(@NonNull Long pk, @NonNull Long bindId);

    /**
     * 单个数据绑定
     *
     * @param pk     绑定的主id
     * @param bindId 绑定的id
     * @return 绑定标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> bind(@NonNull Long pk, @NonNull Long bindId);

    /**
     * 批量数据绑定
     *
     * @param pk         绑定的主id
     * @param bindIdList 绑定的id列表
     * @return 绑定标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> bindBatch(@NonNull Long pk, @NonNull List<Long> bindIdList);

    /**
     * 批量数据绑定
     *
     * @param pkList 绑定的主id列表
     * @param bindId 绑定的id
     * @return 绑定标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> bindBatch(@NonNull List<Long> pkList, @NonNull Long bindId);

    /**
     * 单个数据解绑
     *
     * @param pk       解绑的主id
     * @param unbindId 解绑的id
     * @return 解绑标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> unbind(@NonNull Long pk, @NonNull Long unbindId);

    /**
     * 批量数据解绑
     *
     * @param pk           解绑的主id
     * @param unbindIdList 解绑的id列表
     * @return 解绑标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> unbindBatch(@NonNull Long pk, @NonNull List<Long> unbindIdList);

    /**
     * 根据主id修改绑定关系
     *
     * @param pk1 原id
     * @param pk2 现id
     * @return 修改标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> changeBindByPk(@NonNull Long pk1, @NonNull Long pk2);


    /**
     * 根据副id修改绑定关系
     *
     * @param fk1 原id
     * @param fk2 现id
     * @return 修改标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> changeBindByFk(@NonNull Long fk1, @NonNull Long fk2);

    /**
     * 根据主id删除数据
     *
     * @param pk 主id
     * @return 修改标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> deleteByPk(@NonNull Long pk);


    /**
     * 根据副id删除数据
     *
     * @param fk 副id
     * @return 修改标识
     */
    @Transactional(rollbackFor = Exception.class)
    UpdateModel<Boolean> deleteByFk(@NonNull Long fk);

    /**
     * 获取pk的属性
     *
     * @return pk的属性
     */
    SFunction<PO, Long> getPkExtractor();

    /**
     * 获取fk的属性
     *
     * @return fk的属性
     */
    SFunction<PO, Long> getFkExtractor();

    /**
     * 创建新的对象
     *
     * @param pk 主id
     * @param fk 副id
     * @return 新对象
     */
    PO buildPo(@NonNull Long pk, @NonNull Long fk);

}
